﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace CommandLib
{
    /// <summary>
    /// 封装反射，动态调用程序集
    /// </summary>
    public class RefClass
    {
        private static Dictionary<String, object> AssemblyList = new Dictionary<string, object>();
        /// <summary>
        /// 缓存类实例
        /// </summary>
        private static Dictionary<String, object> InstanceList = new Dictionary<string, object>();
        /// <summary>
        /// 程序集
        /// </summary>
        private Assembly AssemblyData { get; set; }
        /// <summary>
        /// 获取类类型
        /// </summary>
        private Type type { get; set; }
        /// <summary>
        /// 创建类实例
        /// </summary>
        private Object Instance { get; set; }
      

        /// <summary>
        /// 构造实例
        /// </summary>
        /// <param name="assemblyName">程序集名</param>
        /// <param name="ClassName">完整类名</param>
        public RefClass(String assemblyName, String ClassName)
        {

            if (AssemblyList.ContainsKey(assemblyName))
            {
                this.AssemblyData = AssemblyList[assemblyName] as Assembly;
            }
            else
            {
                this.AssemblyData = Assembly.LoadFrom(assemblyName);
                AssemblyList[assemblyName] = this.AssemblyData;
            }
            string AssemblyName = this.AssemblyData.FullName.Split(',')[0] + "." + ClassName;
            this.type = this.AssemblyData.GetType(AssemblyName);
            if (InstanceList.ContainsKey(AssemblyName))
            {
                this.Instance = InstanceList[AssemblyName];
            }
            else
            {
                this.Instance = Activator.CreateInstance(this.type);
                if (this.Instance != null)
                {
                    InstanceList[AssemblyName] = this.Instance;
                }

            }


        }
        /// <summary>
        ///  执行方法
        /// </summary>
        /// <param name="FuncName">方法名</param>
        /// <param name="parm">参数</param>
        /// <param name="IsStatic">是否是静态方法</param>
        /// <returns></returns>
        public object ExecRun(String FuncName, Type[] types = null, Object[] parm = null)
        {
            object result = null;
            try
            {
                if (!String.IsNullOrEmpty(FuncName))
                {
                    if (types == null)
                    {
                        types = new Type[] { };
                    }
                    var method = this.type.GetMethod(FuncName, types);
                    result = method.Invoke(this.Instance, parm);

                }
                else
                {
                    throw new Exception("函数名不能为空！");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return result;
        }

        /// <summary>
        ///  执行方法(返回数据为动太类)
        /// </summary>
        /// <param name="FuncName">方法名</param>
        /// <param name="parm">参数</param>       
        /// <returns></returns>
        public dynamic DyExecRun(String FuncName, Type[] types = null, Object[] parm = null)
        {
            object result = null;
            try
            {
                if (!String.IsNullOrEmpty(FuncName))
                {
                    if (types == null)
                    {
                        types = new Type[] { };
                    }
                    var method = this.type.GetMethod(FuncName, types);
                    result = method.Invoke(this.Instance, parm);
                }
                else 
                {
                    throw new Exception("函数名不能为空！");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return result;
        }

    }
}
